<template>
    <div class="backend-table">
        <!-- 顶部内容 -->
        <div v-if="props.isShowTop" class="backend-table-header d-flex jc-between ai-center">
            <div v-if="searchColumns.length" class="backend-table-search">
                <SearchForm ref="tableSearchForm" :search="search" :reset="reset" :name="name" :searchParam="searchParam"
                    :columns="searchColumns">
                </SearchForm>
            </div>
            <div class="backend-table-left">
                <slot name="header-left" :ids="selectedListIds" :list="selectedList" :isSelected="isSelected"></slot>
            </div>
            <div class="backend-table-right">
                <slot name="header-right" :ids="selectedListIds" :list="selectedList" :isSelected="isSelected"></slot>
            </div>
        </div>
        <el-table v-loading="loading" ref="tableRef" :data="tableData" border :name="`table_${name}`" header-cell-class-name="table-header-name"
            cell-class-name="table-name" @selection-change="selectionChange" :row-key="getRowKeys" class="mt-30" :max-height="props.maxHeight"
            :class="tableData.length == 0 ? 'el-table-empty' : ''" :tree-props="{ children: childrenName }"
            @current-change="handleCurrentChange" @row-click="rowClick">
            <template v-for="item in tableColumns" :key="item">
                <!-- selection || index -->
                <el-table-column v-if="item.type == 'index'" type="index" :width="item.width" :label="item.label"
                    :fixed="item.fixed" :index="indexMethod"></el-table-column>
                <el-table-column v-if="item.type == 'selection'" type="selection" reserve-selection :label="item.label"
                    :width="item.width" :fixed="item.fixed" :selectable="selectable ? handleSelectable : undefined">
                </el-table-column>
                <!-- other -->
                <el-table-column v-if="!item.type && item.prop && item.isShow" :prop="item.prop" :label="item.label" :type="item.type"
                    :min-width="item.width" :sortable="item.sortable" :show-overflow-tooltip="item.prop !== 'operation'"
                    :resizable="true" :fixed="item.fixed">
                    <!-- 自定义 header (使用组件渲染 tsx 语法) -->
                    <template #header v-if="item.renderHeader">
                        <component :is="item.renderHeader" :row="item"> </component>
                    </template>
                    <!-- 自定义配置每一列 slot（使用作用域插槽） -->
                    <template #default="scope">
                        <slot :name="item.prop" :row="scope.row" :index="scope.$index" :pageable="pageable">
                            <!-- 图片(自带预览) -->
                            <el-image v-if="item.image" :src="scope.row[item.prop]"
                                :preview-src-list="[scope.row[item.prop]]" fit="cover" class="table-image"
                                preview-teleported />
                            <!-- tag 标签（自带格式化内容） -->
                            <el-tag v-else-if="item.tag"
                                :type="filterEnum(scope.row[item.prop], item.enum, 'tag')">
                                {{
                                    item.enum?.length ? filterEnum(scope.row[item.prop], item.enum) : defaultFormat(0,
                                0, scope.row[item.prop])
                                }}
                            </el-tag>
                            <!-- 文字（自带格式化内容） -->
                            <span v-else>
                                {{
                                    item.enum?.length ? filterEnum(scope.row[item.prop], item.enum) : defaultFormat(0,
                                0, scope.row[item.prop])
                                }}
                            </span>
                        </slot>
                    </template>
                </el-table-column>
            </template>
			<template #empty>
				<div class="table-empty">
                    <no-data />
				</div>
			</template>
        </el-table>
		<!-- 分页 -->
        <div class="mt-12 d-flex jc-between">
            <div></div>
            <Pagination :pageable="pageable" @getPagination="getPagination"></Pagination>
        </div>
    </div>
</template>
<script setup>
import { useTable } from "@/hooks/useTable";
import { useSelection } from "@/hooks/useSelection";
import { filterEnum, defaultFormat } from "@/utils/utils.js";
import SearchForm from "@/components/SearchForm/index.vue";

const emits = defineEmits(["getTableData", 'handleCurrentChange', 'rowClick']);
// 接受父组件参数，配置默认值
const props = defineProps({
    columns: {  // 表头配置项
        type: Array,
        default: () => []
    },
    pagination: {   // 是否显示分页, 默认 显示
        type: Boolean,
        default: true
    },
    initParam: {    // 默认的请求参数， 如 当前列表打开时默认传参 startTime = '2024-01-01', 配置 initParam = { startTime: '2024-01-01' }
        type: Object,
        default: () => {}
    },
    selectable: {   // 表格可选择时，设置选择列是否可选中
        type: Boolean,
        default: false
    },
    selectableRowName: {    // 表格可选择时，设置选择列 可选中或不可选中的参数判断
        type: String,
        default: ''
    },
    isRequest: {    // 是否请求数据
        type: Boolean,
        default: true
    },
    childrenName: {
        type: String,
        default: 'children'
    },
    name: {
        type: String,
        default: ''
    },
    requestApi: {   // 请求接口
        type: Function,
        default: () => {}
    },
    isShowTop: {    // 是否显示顶部内容 如： 按钮操作， 搜索框等
        type: Boolean,
        default: true
    },
    listId: {   // 列表唯一标识， 默认 id， 有些列表默认标识可能不是id，这时就可传参listId
        type: String,
        default: 'id'
    },
    maxHeight: {
        type: String,
        default: null
    }
})
const tableRef = ref();
// 表格多选 Hooks
const { selectionChange, getRowKeys,selectedListIds,  selectedList, isSelected } = useSelection(props.listId);
// 表格操作 Hooks
const { tableData, moreData, pageable, searchParam, initSearchParam, getTableList, search, reset, getPagination, loading } =
	useTable(props.requestApi, props.initParam, props.pagination, tableRef, props.name);
onMounted(() => {
	if (props.isRequest) getTableList();  
})
// 单选
const handleCurrentChange = (val) => {
	emits("handleCurrentChange", val);
	tableRef.value.setCurrentRow();
}
// 序号
const indexMethod = (index) => {
	const { size, current } = pageable.value;
    if (size == NaN) {
        const number = index + size * (current - 1) + 1;
        return String(number).padStart(4, '0');
    }
    const number = index + 1;
    return String(number).padStart(4, '0');
}
// 表格列配置项处理（添加 isShow 属性，控制显示/隐藏）
const tableColumns = ref();
const searchColumns = ref([])
watch(() => props.columns, (nev) => {
	tableColumns.value = props.columns.map(item => {
		return {
			...item,
			isShow: item.isShow === undefined ? true : item.isShow
		};
	});
	// 过滤需要搜索的配置项
	searchColumns.value = props.columns.filter(item => item.search);

	// 设置搜索表单的默认值
	searchColumns.value.forEach(column => {
		if (column.initSearchParam !== undefined && column.initSearchParam !== null) {
			initSearchParam.value[column.prop] = column.initSearchParam;
			searchParam.value[column.prop] = column.initSearchParam;
		}
	});
	
}, { immediate: true, deep: true })

// 是否可选择
const handleSelectable = (row, index) => {
	return row[props.selectableRowName] === props.selectableRowValue ? false : true;
}
// 刷新
const refreshList = () => {
	getTableList();
	tableRef.value.clearSelection();
	setTimeout(() => {
		emits("getTableData", tableData.value);
	}, 1000);
}
// 自动刷新列表
const autoRefreshList = (isTimer) => {
	getTableList(isTimer);
	setTimeout(() => {
		emits("getTableData", tableData.value);
	}, 1000);
}
// 获取列表数据
const getData = () => {
	return tableData.value
}
// 行点击
let clickRow = {};
const rowClick = (row, column, event) => {
    if (clickRow[props.listId] === row[props.listId]) {
        return
    }
    clickRow = row;
    emits("rowClick", clickRow);
}
// 展开收起
const handleExpandChange = (row) => {
	tableRef.value.toggleRowExpansion(row);
}
// moveUp上移
const moveUp = (index) => {
    if (index === 0) return
    let slotIndex = index;
    const arr = tableData.value[slotIndex];
    tableData.value.forEach((v, k) => {
        if (v[props.listId] === arr[props.listId]) {
            tableData.value.splice(k, 1)
        }
    })
    if (slotIndex > 0) {
        slotIndex = slotIndex - 1;
    } else {
        slotIndex = 0;
    }
    tableData.value.splice(slotIndex, 0, [arr]);
    tableData.value = tableData.value.flat();
}
// moveDown下移
const moveDown = (index) => {
    if (index === pageable.value.size || index === pageable.value.total - 1) return
    let slotIndex = index;
    const arr = tableData.value[slotIndex];
    tableData.value.forEach((v, k) => {
        if (arr[props.listId] === v[props.listId]) {
            tableData.value.splice(k, 1)
        }
    })
    if (slotIndex > 0) {
        slotIndex = slotIndex + 1;
    } else {
        slotIndex = 1;
    }
    tableData.value.splice(slotIndex, 0, [arr]);
    tableData.value = tableData.value.flat();
}

// 暴露给父组件的参数和方法
defineExpose({ searchParam, refresh: refreshList, autoRefresh: autoRefreshList, getData, handleExpandChange, moveUp, moveDown });
</script>

<style lang="scss" scoped>
.table-empty {
    padding-top: 50px;
    padding-bottom: 50px;
    line-height: 0;
}
.backend-table {
    
    :deep(.el-table) {
        // border: 1px solid #C7C7C7;
        & th.el-table__cell.is-leaf,
        & td.el-table__cell {
            border-bottom: 1px solid #C7C7C7;
        }
        &::after, &::before, & .el-table__inner-wrapper::after, .el-table__inner-wrapper::before {
            background-color: #C7C7C7
        }
        & .el-table__cell {
            border-right: 0;
        }
        & th.el-table__cell {
            background-color: #F0F6FE;
        }
        &::before {
            left: 1px;
        }
        tr {
            background-color: #F8FBFF;
        }
        & .el-table__body tr:hover > td.el-table__cell {
            background-color: #F0F6FE;
        }
        .el-checkbox {
            &__inner {
                width: 18px;
                height: 18px;
                border: 1px solid #8D8D8E;
                &:hover {
                    border: 1px solid #080404;
                }
                &::after {
                    width: 6px;
                    height: 10px;
                    left: 35%;
                    top: 12%;
                }
            }
            &.is-checked {
                .el-checkbox__inner {
                    background-color: #080404;
                    border: 0;
                }
            }
            &__input {
                &.is-indeterminate {
                    .el-checkbox__inner {
                        background-color: #080404;
                        border: 0;
                        &::before {
                            background-color: #fff;
                            height: 3px;
                            top: 45%;
                        }
                    }
                }
            }
        }
        .table-header-name {
            font-size: 16px;
            color: $main-color;
            font-weight: 500;
        }
        .table-name,
        .table-name .row-name{
            font-size: 14px;
            color: $main-color;
            font-weight: normal;
        }
    }
}

</style>